package com.jingtai.platform.service.admin.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jingtai.common.constants.CommonConstant;
import com.jingtai.common.constants.RedisConstant;
import com.jingtai.common.enums.AccountStatusEnum;
import com.jingtai.common.enums.DeleteFlagEnum;
import com.jingtai.common.template.ResultMapInfo;
import com.jingtai.common.utils.EncryptUtil;
import com.jingtai.common.utils.MyBeanUtils;
import com.jingtai.common.webfacade.error.CommonException;
import com.jingtai.common.webfacade.error.ErrorEnum;
import com.jingtai.core.entity.admin.PlatformAccount;
import com.jingtai.core.entity.member.MemberInfo;
import com.jingtai.core.mapper.admin.PlatformAccountMapper;
import com.jingtai.platform.config.JwtConfig;
import com.jingtai.platform.service.admin.PlatformAccountService;
import com.jingtai.platform.util.JwtTokenUtils;
import com.jingtai.platform.util.ResultUtil;
import com.jingtai.platform.util.UrlToMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


/**
 * 平台账户表 impl
 *
 * @author sunlaiqian
 * @date 2020-12-02 18:31:32
 */
@Service
public class PlatformAccountServiceImpl extends ServiceImpl<PlatformAccountMapper, PlatformAccount> implements PlatformAccountService {

    @Autowired
    private PlatformAccountService platformAccountService;
    @Resource
    private JwtTokenUtils jwtTokenUtils;
    @Resource
    private RedisTemplate<String, String> redisTemplate;
    @Resource
    private JwtConfig jwtConfig;

    @Override
    public ResultUtil PlatformAccountlist(Integer page, Integer limit, String conditions) {
        QueryWrapper<PlatformAccount> wrapper = new QueryWrapper<>();
        Map<String, String> map = UrlToMap.paramToMap(conditions);
        for (Map.Entry<String, String> entry : map.entrySet()) {
            wrapper.like(entry.getKey(), entry.getValue());
        }
        wrapper.eq("delete_flag", DeleteFlagEnum.NOT_DELETE.getCode());
        return new ResultUtil(ResultMapInfo.GETSUCCESS, platformAccountService.page(new Page<>(page, limit), wrapper).getRecords());
    }

    @Override
    public ResultUtil addPlatformAccount(PlatformAccount platformAccount) {
        PlatformAccount existUserName = platformAccountService.getOne(Wrappers.lambdaQuery(PlatformAccount.class).eq(PlatformAccount::getUserName, platformAccount.getUserName())
                .eq(PlatformAccount::getDeleteFlag, DeleteFlagEnum.NOT_DELETE.getCode()));
        if (ObjectUtil.isNotEmpty(existUserName)) {
            return new ResultUtil(ResultMapInfo.USEREXIST);
        }

        PlatformAccount existUserPhone = platformAccountService.getOne(Wrappers.lambdaQuery(PlatformAccount.class).eq(PlatformAccount::getPlatformPhone, platformAccount.getPlatformPhone())
                .eq(PlatformAccount::getDeleteFlag, DeleteFlagEnum.NOT_DELETE.getCode()));
        if (ObjectUtil.isNotEmpty(existUserPhone)) {
            return new ResultUtil(ErrorEnum.PHONE_NUMBER_OCCUPY);
        }

        platformAccount.setPassWord(EncryptUtil.Base64Encode(platformAccount.getPassWord()));
        boolean save = platformAccountService.save(platformAccount);
        return new ResultUtil(save ? ResultMapInfo.ADDSUCCESS : ResultMapInfo.ADDFAIL);
    }

    @Override
    public ResultUtil getPlatformAccountById(Long id) {
        PlatformAccount platformAccount = platformAccountService.getById(id);
        return platformAccount == null ? new ResultUtil(ResultMapInfo.GETFAIL) : new ResultUtil(ResultMapInfo.GETSUCCESS, platformAccount);
    }

    @Override
    public ResultUtil delPlatformAccountById(Long id) {
        PlatformAccount platformAccount = new PlatformAccount();
        platformAccount.setId(id);
        platformAccount.setDeleteFlag(DeleteFlagEnum.DELETE.getCode());
        boolean delState = platformAccountService.updateById(platformAccount);
        return delState ? new ResultUtil(ResultMapInfo.DELETESUCCESS) : new ResultUtil(ResultMapInfo.DELETEFAIL);
    }

    @Override
    public ResultUtil platformLogin(PlatformAccount platformAccount) {
        PlatformAccount existPlatformNameOrPhone = platformAccountService.getOne(Wrappers.lambdaQuery(PlatformAccount.class)
                .and(wrapper -> wrapper.eq(PlatformAccount::getUserName, platformAccount.getUserName())
                        .or()
                        .eq(PlatformAccount::getPlatformPhone, platformAccount.getUserName()))
                .eq(PlatformAccount::getDeleteFlag, DeleteFlagEnum.NOT_DELETE.getCode()));
        if (ObjectUtil.isEmpty(existPlatformNameOrPhone)) {
            return new ResultUtil(ErrorEnum.NOT_INVALID_PHONE_NAME);
        }

        if (ObjectUtil.equal(AccountStatusEnum.LOGOUT.getValue(), existPlatformNameOrPhone.getEnableState())) {
            return new ResultUtil(ResultMapInfo.USERLOGOUT);
        }

        if (ObjectUtil.equal(AccountStatusEnum.FREEZE.getValue(), existPlatformNameOrPhone.getEnableState())) {
            return new ResultUtil(ResultMapInfo.SHOPUSERFROZEN);
        }

        String reducePassword = EncryptUtil.Base64Decode(existPlatformNameOrPhone.getPassWord());
        if (!StringUtils.equals(reducePassword, platformAccount.getPassWord())) {
            return new ResultUtil(ResultMapInfo.OLDPASSWORDERROR);
        }

        //相当于把userId设置成主键-->token
        String token = jwtTokenUtils.generateToken(existPlatformNameOrPhone.getUserName(), existPlatformNameOrPhone.getId());

        redisTemplate.opsForValue().set(RedisConstant.TOKEN_LOGIN_PLATFORM_PRE_KEY + existPlatformNameOrPhone.getId(),
                jwtTokenUtils.setTokenToRedis(token),
                jwtConfig.getExpiration(), TimeUnit.HOURS);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("token",jwtConfig.getTokenStart() + " " + token);
        jsonObject.put("data",existPlatformNameOrPhone);
        return new ResultUtil(ResultMapInfo.LOGINSUCCESS, jsonObject);
    }

    @Override
    public ResultUtil platformLogOut(HttpServletRequest request) {
        Long id = jwtTokenUtils.getUserIdFromToken(request);
        redisTemplate.delete(RedisConstant.TOKEN_LOGIN_PLATFORM_PRE_KEY + id);
        return new ResultUtil(ResultMapInfo.LOGOTSUCCESS);
    }

    @Override
    public ResultUtil unLock(Long id,String password) {
        PlatformAccount one = platformAccountService.getOne(Wrappers.lambdaQuery(PlatformAccount.class).eq(PlatformAccount::getId, id).eq(PlatformAccount::getPassWord, EncryptUtil.Base64Encode(password)));
        return one != null ? new ResultUtil(ResultMapInfo.OPERATE_SUCCESS) : new ResultUtil(ResultMapInfo.OPERATE_FAIL);
    }

    @Override
    public ResultUtil editPlatformAccount(PlatformAccount platformAccount) {
        boolean editState = platformAccountService.updateById(platformAccount);
        return editState ? new ResultUtil(ResultMapInfo.EDITSUCCESS) : new ResultUtil(ResultMapInfo.EDITFAIL);
    }

}
